//package org.easier.framework.elasticsearch.estemplate.impl;
//
//
//import org.elasticsearch.action.DocWriteResponse;
//import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
//import org.elasticsearch.action.delete.DeleteRequest;
//import org.elasticsearch.action.delete.DeleteResponse;
//import org.elasticsearch.action.get.GetRequest;
//import org.elasticsearch.action.get.GetResponse;
//import org.elasticsearch.action.index.IndexRequest;
//import org.elasticsearch.action.index.IndexResponse;
//import org.elasticsearch.action.search.SearchRequest;
//import org.elasticsearch.action.search.SearchResponse;
//import org.elasticsearch.action.support.master.AcknowledgedResponse;
//import org.elasticsearch.action.support.replication.ReplicationResponse;
//import org.elasticsearch.action.update.UpdateRequest;
//import org.elasticsearch.action.update.UpdateResponse;
//import org.elasticsearch.client.RequestOptions;
//import org.elasticsearch.client.RestHighLevelClient;
//import org.elasticsearch.client.indices.CreateIndexRequest;
//import org.elasticsearch.client.indices.CreateIndexResponse;
//import org.elasticsearch.client.indices.GetIndexRequest;
//import org.elasticsearch.client.indices.GetIndexResponse;
//import org.elasticsearch.common.lucene.search.function.CombineFunction;
//import org.elasticsearch.common.lucene.search.function.FieldValueFactorFunction;
//import org.elasticsearch.common.unit.TimeValue;
//import org.elasticsearch.common.xcontent.XContentBuilder;
//import org.elasticsearch.common.xcontent.XContentFactory;
//import org.elasticsearch.common.xcontent.XContentType;
//import org.elasticsearch.index.query.*;
//import org.elasticsearch.index.query.functionscore.FieldValueFactorFunctionBuilder;
//import org.elasticsearch.search.SearchHit;
//import org.elasticsearch.search.builder.SearchSourceBuilder;
//import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
//import org.elasticsearch.search.sort.FieldSortBuilder;
//import org.elasticsearch.search.sort.SortBuilder;
//import org.elasticsearch.search.sort.SortBuilders;
//import org.elasticsearch.search.sort.SortOrder;
//
//import java.io.IOException;
//import java.time.format.DateTimeFormatter;
//
//
//public class QueryBuilderHelper {
//    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//
//
//
//
//    public QueryBuilder getQueryBuilder(Search search, SortFun sortFun) {
//        if (sortFun == null) {
//            return getQueryBuilder(search, OperatorTypes.AND);
//        }
//
//        FieldValueFactorFunctionBuilder fieldQuery = new FieldValueFactorFunctionBuilder(
//                sortFun.getKey());
//        fieldQuery.factor(sortFun.getFactor());
//        fieldQuery.modifier(FieldValueFactorFunction.Modifier.LOG1P);
//
//        return QueryBuilders.functionScoreQuery(getQueryBuilder(search, OperatorTypes.AND), fieldQuery).boostMode(CombineFunction.SUM);
//    }
//
//    public BoolQueryBuilder getQueryBuilder(Search search, OperatorTypes operatorType) {
//        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//        if (search.getClass() != BoolSearch.class) {
//            return boolQueryBuilder;
//        }
//
//        BoolSearch boolSearch = (BoolSearch) search;
//        for (Search item : boolSearch.getSearches()) {
//            if (item instanceof TextSearch) {
//                TextSearch textSearch = (TextSearch) item;
//                MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery(textSearch.getKey(), textSearch.getValue());
//                setOperator(boolQueryBuilder, operatorType, matchQueryBuilder);
//                if (textSearch.getBoost() != 0) {
//                    matchQueryBuilder.boost(textSearch.getBoost());
//                }
//            }
//
//            if (item instanceof KeyWordSearch) {
//                KeyWordSearch keyWordSearch = (KeyWordSearch) item;
//                TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(keyWordSearch.getKey(), keyWordSearch.getValue());
//                if (operatorType != OperatorTypes.OR) {
//                    boolQueryBuilder.filter(termQueryBuilder);
//                } else {
//                    setOperator(boolQueryBuilder, operatorType, QueryBuilders.boolQuery().filter(termQueryBuilder));
//                }
//            }
//
//            if (item instanceof KeyWordsSearch) {
//                KeyWordsSearch keyWordsSearch = (KeyWordsSearch) item;
//                TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery(keyWordsSearch.getKey(), keyWordsSearch.getValue());
//                if (operatorType != OperatorTypes.OR) {
//                    boolQueryBuilder.filter(termsQueryBuilder);
//                } else {
//                    setOperator(boolQueryBuilder, operatorType, QueryBuilders.boolQuery().filter(termsQueryBuilder));
//                }
//            }
//
//            if (item instanceof RangeSearch) {
//                RangeSearch range = (RangeSearch) item;
//                RangeQueryBuilder builder = QueryBuilders.rangeQuery(range.getKey());
//                if (range.getGtValue() != null) {
//                    builder.gt(range.getGtValue());
//                }
//                if (range.getGteValue() != null) {
//                    builder.gte(range.getGteValue());
//                }
//                if (range.getLtValue() != null) {
//                    builder.lt(range.getLtValue());
//                }
//                if (range.getLteValue() != null) {
//                    builder.lte(range.getLteValue());
//                }
//                if (operatorType != OperatorTypes.OR) {
//                    boolQueryBuilder.filter(builder);
//                } else {
//                    setOperator(boolQueryBuilder, operatorType, QueryBuilders.boolQuery().filter(builder));
//                }
//            }
//            if (item instanceof DateRangeSearch) {
//                DateRangeSearch dateRangeSearch = (DateRangeSearch) item;
//                RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery(dateRangeSearch.getKey());
//                if (dateRangeSearch.getGtValue() != null) {
//                    rangeQueryBuilder.gt(formatter.format(dateRangeSearch.getGtValue()));
//                }
//                if (dateRangeSearch.getGteValue() != null) {
//                    rangeQueryBuilder.gt(formatter.format(dateRangeSearch.getGteValue()));
//                }
//                if (dateRangeSearch.getLtValue() != null) {
//                    rangeQueryBuilder.gt(formatter.format(dateRangeSearch.getLtValue()));
//                }
//                if (dateRangeSearch.getLteValue() != null) {
//                    rangeQueryBuilder.gt(formatter.format(dateRangeSearch.getLteValue()));
//                }
//                rangeQueryBuilder.timeZone(dateRangeSearch.getTimeZone());
//                if (operatorType != OperatorTypes.OR) {
//                    boolQueryBuilder.filter(rangeQueryBuilder);
//                } else {
//                    setOperator(boolQueryBuilder, operatorType, QueryBuilders.boolQuery().filter(rangeQueryBuilder));
//                }
//            }
//            if (item instanceof NumberSearch) {
//                NumberSearch numberSearch = (NumberSearch) item;
//                TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(numberSearch.getKey(), numberSearch.getValue());
//                if (operatorType != OperatorTypes.OR) {
//                    boolQueryBuilder.filter(termQueryBuilder);
//                } else {
//                    setOperator(boolQueryBuilder, operatorType, QueryBuilders.boolQuery().filter(termQueryBuilder));
//                }
//            }
//
//            if (item instanceof BoolSearch) {
//                setOperator(boolQueryBuilder, operatorType, getQueryBuilder(item, ((BoolSearch) item).getOperatorType()));
//            }
//        }
//        return boolQueryBuilder;
//    }
//
//    private void setOperator(BoolQueryBuilder boolQueryBuilder, OperatorTypes types, QueryBuilder queryBuilder) {
//        if (types == OperatorTypes.AND) {
//            boolQueryBuilder.must(queryBuilder);
//        } else if (types == OperatorTypes.OR) {
//            boolQueryBuilder.should(queryBuilder);
//        } else if (types == OperatorTypes.NOT) {
//            boolQueryBuilder.mustNot(queryBuilder);
//        }
//    }
//}
